package cn.iocoder.yudao.module.hs.service.entryorderdetail;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.hs.controller.admin.entryorderdetail.vo.EntryOrderDetailPageReqVO;
import cn.iocoder.yudao.module.hs.controller.admin.entryorderdetail.vo.EntryOrderDetailRespVO;
import cn.iocoder.yudao.module.hs.controller.admin.entryorderdetail.vo.EntryOrderDetailSaveReqVO;
import cn.iocoder.yudao.module.hs.dal.dataobject.entryorder.EntryOrderDO;
import cn.iocoder.yudao.module.hs.dal.dataobject.entryorderdetail.EntryOrderDetailDO;
import cn.iocoder.yudao.module.hs.dal.dataobject.material.MaterialDO;
import cn.iocoder.yudao.module.hs.dal.dataobject.tray.TrayDO;
import cn.iocoder.yudao.module.hs.dal.mysql.entryorderdetail.EntryOrderDetailMapper;
import cn.iocoder.yudao.module.hs.enums.warehouse.WarehouseTypeEnum;
import cn.iocoder.yudao.module.hs.service.entryorder.EntryOrderService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.hs.enums.ErrorCodeConstants.ENTRY_ORDER_DETAIL_NOT_EXISTS;
import static cn.iocoder.yudao.module.hs.enums.ErrorCodeConstants.ENTRY_ORDER_NOT_EXISTS;

/**
 * 入库单明细 Service 实现类
 *
 * @author 航盛
 */
@Service
@Validated
public class EntryOrderDetailServiceImpl implements EntryOrderDetailService {

    @Resource
    private EntryOrderDetailMapper entryOrderDetailMapper;
    @Resource
    private EntryOrderService entryOrderService;

    @Override
    public Long createEntryOrderDetail(EntryOrderDetailSaveReqVO createReqVO) {
        // 插入
        EntryOrderDetailDO entryOrderDetail = BeanUtils.toBean(createReqVO, EntryOrderDetailDO.class);
        entryOrderDetailMapper.insert(entryOrderDetail);
        // 返回
        return entryOrderDetail.getId();
    }

    @Override
    public void updateEntryOrderDetail(EntryOrderDetailSaveReqVO updateReqVO) {
        // 校验存在
        validateEntryOrderDetailExists(updateReqVO.getId());
        // 更新
        EntryOrderDetailDO updateObj = BeanUtils.toBean(updateReqVO, EntryOrderDetailDO.class);
        entryOrderDetailMapper.updateById(updateObj);
    }

    @Override
    public void deleteEntryOrderDetail(Long id) {
        // 校验存在
        validateEntryOrderDetailExists(id);
        // 删除
        entryOrderDetailMapper.deleteById(id);
    }

    private void validateEntryOrderDetailExists(Long id) {
        if (entryOrderDetailMapper.selectById(id) == null) {
            throw exception(ENTRY_ORDER_DETAIL_NOT_EXISTS);
        }
    }

    @Override
    public EntryOrderDetailDO getEntryOrderDetail(Long id) {
        return entryOrderDetailMapper.selectById(id);
    }

    @Override
    public PageResult<EntryOrderDetailRespVO> getEntryOrderDetailPage(EntryOrderDetailPageReqVO pageReqVO) {
        EntryOrderDO entryOrder = entryOrderService.getEntryOrder(pageReqVO.getOrderId());
        if (entryOrder == null) {
            throw exception(ENTRY_ORDER_NOT_EXISTS);
        }
        if (WarehouseTypeEnum.PRODUCTION.getType().equals(entryOrder.getWarehouseType())) {
            PageResult<EntryOrderDetailDO> entryOrderDetailDOPageResult = entryOrderDetailMapper.selectPage(pageReqVO);
            return BeanUtils.toBean(entryOrderDetailDOPageResult, EntryOrderDetailRespVO.class);
        }
        Page<EntryOrderDetailRespVO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        IPage<EntryOrderDetailRespVO> entryOrderDetailRespVOIPage = entryOrderDetailMapper.selectPageNotEntryRecord(page, pageReqVO);
        PageResult<EntryOrderDetailRespVO> pageResult = new PageResult<>();
        pageResult.setList(entryOrderDetailRespVOIPage.getRecords());
        pageResult.setTotal(entryOrderDetailRespVOIPage.getTotal());
        return pageResult;
    }

    @Override
    public void insertEnterOrderDetail(TrayDO tray, MaterialDO material) {
        List<EntryOrderDetailDO> entryOrderDetailDOS = entryOrderDetailMapper.selectList(EntryOrderDetailDO::getTrayCode, tray.getCode(), EntryOrderDetailDO::getWarehouseId, tray.getWarehouseId());
        if (CollUtil.isNotEmpty(entryOrderDetailDOS)) {
            Long entryOrderId = entryOrderDetailDOS.get(0).getOrderId();
            EntryOrderDetailDO entryOrderDetailDO = buildEntryOrderDetail(entryOrderId, material, tray.getRfidCode(), tray.getWarehouseId());
            entryOrderDetailMapper.insert(entryOrderDetailDO);
        }
    }

    private EntryOrderDetailDO buildEntryOrderDetail(Long entryOrderId, MaterialDO material, String rfidCode,
                                                     Long warehouseId) {
        EntryOrderDetailDO orderDetail = new EntryOrderDetailDO();
        orderDetail.setOrderId(entryOrderId);
        orderDetail.setTrayCode(material.getTrayCode());
        orderDetail.setBoxCode(material.getBoxCode());
        orderDetail.setMaterialCode(material.getCode());
        orderDetail.setMaterialName(material.getName());
        orderDetail.setModeCode(material.getModeCode());
        orderDetail.setRfidCode(rfidCode);
        orderDetail.setWarehouseId(warehouseId);
        orderDetail.setEntryTime(LocalDateTime.now());
        return orderDetail;
    }

}